<?php
/**
 * Created by PhpStorm.
 * User: 刘翰文
 * Date: 2018/8/30
 * Time: 13:48
 */

namespace app\api\service;

require '../extend/WxPay/WxPay.Api.php';

use app\api\model\OrderMaster;
use app\exception\payExceptions;
use think\Loader;
use think\Log;
use WxPay\WxPayNotifyReply;
use WxPay\WxPayApi;
use WxPay\WxPayConfigInterface;

//Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');


class WxNotify extends WxPayNotifyReply
{
    public function NotifyProcess($objData, $config, &$msg)
    {
        if ($objData->values['result_code'] == 'SUCCESS') {
            $orderNo = $objData->values['out_trade_no'];
            try {
                OrderMaster::update([
                    'pay_status' => 1,
                    'order_status' =>1
                ],[
                    'order_id' => $orderNo
                ]);
            } catch (\Exception $ex) {
                //Log::error('回调失败'.$objData);
                throw new payExceptions(['msg'=>['ss'=>'回调失败','data'=>$objData,'ex'=>$ex]]);
                // 如果出现异常，向微信返回false，请求重新发送通知
                return false;
            }
        }
        return true;
    }

    private $config = null;
    /**
     *
     * 回调入口
     * @param bool $needSign  是否需要签名返回
     */
    final public function Handle($needSign = true)
    {
        $this->config = new WxPayConfig();
        $msg = "OK";
        //当返回false的时候，表示notify中调用NotifyCallBack回调失败获取签名校验失败，此时直接回复失败
        $result = WxpayApi::notify($this->config, array($this, 'NotifyCallBack'), $msg);
        if($result == false){
            $this->SetReturn_code("FAIL");
            $this->SetReturn_msg($msg);
            $this->ReplyNotify(false);
            return;
        } else {
            //该分支在成功回调到NotifyCallBack方法，处理完成之后流程
            $this->SetReturn_code("SUCCESS");
            $this->SetReturn_msg("OK");
        }
        $this->ReplyNotify($needSign);
    }

    /**
     *
     * 回调方法入口，子类可重写该方法
    //TODO 1、进行参数校验
    //TODO 2、进行签名验证
    //TODO 3、处理业务逻辑
     * 注意：
     * 1、微信回调超时时间为2s，建议用户使用异步处理流程，确认成功之后立刻回复微信服务器
     * 2、微信服务器在调用失败或者接到回包为非确认包的时候，会发起重试，需确保你的回调是可以重入
     * @param WxPayNotifyResults $objData 回调解释出的参数
     * @param WxPayConfigInterface $config
     * @param string $msg 如果回调处理失败，可以将错误信息输出到该方法
     * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
     */


    /**
     *
     * 业务可以继承该方法，打印XML方便定位.
     * @param string $xmlData 返回的xml参数
     *
     **/
    public function LogAfterProcess($xmlData)
    {
        return;
    }

    /**
     *
     * notify回调方法，该方法中需要赋值需要输出的参数,不可重写
     * @param array $data
     * @return true回调出来完成不需要继续回调，false回调处理未完成需要继续回调
     */
    final public function NotifyCallBack($data)
    {
        $msg = "OK";
        $result = $this->NotifyProcess($data, $this->config, $msg);

        if($result == true){
            $this->SetReturn_code("SUCCESS");
            $this->SetReturn_msg("OK");
        } else {
            $this->SetReturn_code("FAIL");
            $this->SetReturn_msg($msg);
        }
        return $result;
    }

    /**
     *
     * 回复通知
     * @param bool $needSign 是否需要签名输出
     */
    final private function ReplyNotify($needSign = true)
    {
        //如果需要签名
        if($needSign == true &&
            $this->GetReturn_code() == "SUCCESS")
        {
            $this->SetSign($this->config);
        }

        $xml = $this->ToXml();
        $this->LogAfterProcess($xml);
        WxpayApi::replyNotify($xml);
    }

}